概述
Sentinel是一个以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务稳定性的分布式系统流量防控兵。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
注:以上描述摘自 Sentinel官方文档
在本篇中,我们将使用Sentinel对服务进行流量控制、熔断降级以及基于nacos的规则持久化
创建项目
首先,我们来创建一个 SpringBoot 项目,就起名sentinel-test吧。
然后,引入如下依赖:
1 | <dependency> |
流量控制
项目创建完成后,让我们来测试一下Sentinel的流量控制。在Sentinel中,流量控制是通过抛出BlockException来实现的,我们可以通过@SentinelResource来标记资源和处理异常的方法,共有两种方式:
- 在单独类中处理异常:使用blockHandlerClass来指定处理异常的类,使用blockHandler指定类中处理异常的方法,这个方法必须是一个静态方法,且要求该静态方法的参数列表在被标记的资源基础上,添加一个BlockException,参考后续代码中的/test1
- 在本类中处理异常: 使用blockHandler指定本类中的一个处理异常的方法,要求该静态方法的参数列表在被标记的资源基础上,添加一个BlockException,参考后续代码中的/test2
1 |
|
下面,我们来设定具体的流量控制规则,流控规则也是以资源为切入点的,我们可以通过代码来配置,也可以通过外Sentinel控制台来配置。
方式一:代码配置
1 |
|
OK,下面我们启动项目进行测试,让我们疯狂访问/test1和/test2接口,会看到类似下面的提示:
请求资源 : test1
流量控制 : test1
流量控制 : test1
请求资源 : test1
流量控制 : test1
流量控制 : test1
表明流量控制起到了作用,如果我们将流控的阈值设置的比较大,手动刷新时就基本不会出现流量控制的情况了,因为我们的手速并没有那么快。
当然,流控的规则并不是只有QPS一种,文末会给出一些配置项的具体说明,在这里就不细说了。
熔断降级
除了流量控制,Sentinel还提供了熔断降级机制,比如当一个接口频繁出现错误时,Sentinel就会按照配置的降级规则对接口进行降级处理。
Sentinel的熔断降级是通过DegradeException来实现的,下面我们来模拟一下这种情况。
1 |
|
在上面的流量控制中,我们采用了硬编码的方式来定义流控规则,在本小节,我们通过Sentinel Dashboard来配置降级规则。
我们需要去下载 Sentinel DashBoard,这是一个基于SpringBoot编写的程序,打包成jar包供我们使用。
通过命令 java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar启动,端口号可以根据需要去进行修改,我这里改为8899
访问localhost:8899就可以看到Sentinel Dashboard了
接下来,我们修改一下项目的配置,在application.yml中进行如下配置:
1 | spring: |
请注意,我们这里配置了一个8103的端口号,sentinel会自动在这个端口启动一个Http服务,并通过这个服务与dashboard进行通信,这样一来,我们在dashboard上添加的降级规则就会被推送到我们的项目中。
在dashboard中,我们对资源test3新增一条降级规则,这里采用异常比例规则,取值0.1表示当每秒钟出现异常的比例达到十分之一,就对资源降级10秒钟。
这里有一个特别注意的点,上图的降级规则中有一项是异常数,这个表示的是1分钟内的异常数,如果我们使用这个规则,且降级时间设定的小于一分钟,那么就有可能出现资源已经超过降级时间窗口,但依然是被降级的状态。
下面我们启动项目进行测试,让我们疯狂访问/test3,会看到类似下面的提示:
请求资源 : test3
业务出现异常 = Thu Jun 04 10:37:51 CST 2020
服务已被降级 = Thu Jun 04 10:37:52 CST 2020
服务已被降级 = Thu Jun 04 10:37:53 CST 2020
服务已被降级 = Thu Jun 04 10:37:54 CST 2020
服务已被降级 = Thu Jun 04 10:37:55 CST 2020
表明熔断降级起到了作用。
规则持久化
虽然通过Sentinel Dashboard来设置规则可以避免硬编码的方式,但Dashboard中的规则是基于内存来存储的,重启后就会消失,而我们希望通过持久化的方式来存储规则。我们就可以借助Nacos配置中心来实现这个目标,关于Nacos的配置和启动这里就不再赘述了。
首先,添加依赖
1 | <dependency> |
然后修改配置如下:
1 | spring: |
在Nacos控制台中创建如下所示的配置:
注意这两个配置都是json格式,内容如下:
sentinel-test-flow:
1 | [ |
sentinel-test-degrade
1 | [ |
ok,启动项目后,再次进行测试,我们就会得到和之前测试相同的结果了。
到这里,关于Sentinel的流控和熔断降级就实验完成了,其实Sentinel提供给我们的功能还远不止这些,其他的热点参数限流、集群限流、网关限流等也都是很实用的流控策略,相信通过本篇的流控和熔断降级的实验,其他策略的使用也不在话下了。
最后,对一些配置参数进行简单的说明
FlowRule(流控规则)
字段 | 描述 | 默认值 |
---|---|---|
resource | 资源名 | |
limitApp | 针对的调用来源,若为 default 则不区分调用来源 | default |
grade | 限流阈值类型(QPS或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制 | QPS模式 |
count | 限流阈值 | |
strategy | 调用关系限流策略(0表示调用方直接限流、1表示关联资源限流、2表示链路限流) | |
controlBehavior | 调用关系限流策略(0表示调用方直接限流、1表示关联资源限流、2表示链路限流) | 拒绝 |
clusterMode | 是否为集群模式 | clusterMode |
DegradeRule(熔断降级规则)
字段 | 描述 | 默认值 |
---|---|---|
resource | 资源名 | |
limitApp | 针对的调用来源,若为 default 则不区分调用来源 | default |
count | 阈值 | |
grade | 降级模式,根据RT(0) 、每秒异常比例(1)、60s内异常数(2) | RT(0) |
timeWindow | 降级的时间,单位为秒 |
源码地址:https://github.com/GreedyStar/spring-cloud-alibaba-demo
最后的最后,安利一下自己写的一个Java代码生成工具,能够方便的生成Spring、SpringMVC、Mybatis架构下的Java代码,希望能对大家有所帮助,地址:Java代码生成器:Generator